package com.ecarx.vhaltests.hy11.testcases.climate;

import static com.ecarx.vhaltests.VhalUnitTestBase2.getIpcpClient;
import static com.ecarx.xui.adaptapi.car.hvac.IHvac.HVAC_FUNC_AUTO_STEERING_WHEEL_HEAT_SWITCH;
import static com.ecarx.xui.adaptapi.car.vehicle.IDriveMode.DM_FUNC_DRIVE_MODE_SELECT;
import static com.ecarx.xui.adaptapi.car.vehicle.IDriveMode.DRIVE_MODE_SELECTION_ECO;
import static com.ecarx.xui.adaptapi.car.vehicle.IDriveMode.DRIVE_MODE_SELECTION_NORMAL;


import android.car.VehicleAreaType;
import android.car.hardware.CarPropertyValue;
import android.car.hardware.property.CarPropertyManager;
import android.util.Log;

import androidx.test.platform.app.InstrumentationRegistry;

import com.ecarx.vhaltests.IpcpClient;
import com.ecarx.vhaltests.VehicleConstants;
import com.ecarx.vhaltests.VhalUnitTestBase;
import com.ecarx.xui.adaptapi.car.IWrapper;

import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;


// 3.2.19 [SW_FC_003_025]方向盘加热SteerWhlHeatg---自动加热开关
public class HvacFuncAutoSteeringWheelHeatSwitchTest extends VhalUnitTestBase {
    public static final String TAG = "HVAC_FUNC_AUTO_STEERING_WHEEL_HEAT_SWITCH";
    private static IWrapper.IPropertyId propertyId;
    private static IWrapper.IPropertyId driveModePropertyId;
    protected static IWrapper wrapper;
    private static boolean halValue;
    private static int halStatus;
    final static Object lock = new Object();
    private static final IpcpClient ipcpClient = new IpcpClient();


    @BeforeClass
    public static void testInit() {
        wrapper = com.ecarx.xui.adaptapi.car.Car.createWrapper(InstrumentationRegistry.getInstrumentation().getTargetContext());
        propertyId = wrapper.getWrappedPropertyId(IWrapper.WrappedIdType.ID_TYPE_FUNCTION, HVAC_FUNC_AUTO_STEERING_WHEEL_HEAT_SWITCH);
        driveModePropertyId = wrapper.getWrappedPropertyId(IWrapper.WrappedIdType.ID_TYPE_FUNCTION, DM_FUNC_DRIVE_MODE_SELECT);
        mCarPropertyMgr.registerCallback(carPropertyEventCallback, propertyId.getPropertyId(), CarPropertyManager.SENSOR_RATE_ONCHANGE);
        setConfig();
    }

    @Test
    public void testAutoSteeringWheelHeatSwitchNotAvailable() {
        setAutoSteeringWheelHeatSwitchNotAvail();
        lockWait();
        Assert.assertEquals(halStatus, 1);
        testAutoSteeringWheelHeatSwitchNotAvail();
    }

    @Test
    public void testAutoSteeringWheelHeatSwitchAvailable() {
        setAutoSteeringWheelHeatSwitchAvail();
        lockWait();
        Assert.assertEquals(halStatus, 0);
        testAutoSteeringWheelHeatSwitchIsAvail();
    }

    @Test
    public void testAutoSteeringWheelHeatSwitchTrue() {
        setAutoSteeringWheelHeatSwitchAvail();
        setAutoSteeringWheelHeatSwitchValue(true);
        lockWait();
        Assert.assertTrue(halValue);
        Assert.assertEquals(halStatus, 0);
        testAutoSteeringWheelHeatSwitchValue(true);
    }

    @Test
    public void testAutoSteeringWheelHeatSwitchFalse() {
        setAutoSteeringWheelHeatSwitchAvail();
        setAutoSteeringWheelHeatSwitchValue(false);
        lockWait();
        Assert.assertFalse(halValue);
        Assert.assertEquals(halStatus, 0);
        testAutoSteeringWheelHeatSwitchValue(false);
    }

    @Test
    public void testAutoSteerWheelHeatOtherToDriverLastTrue() {//other->driver 触发的恢复上次设置的值，上次值为true
        setAutoSteeringWheelHeatSwitchAvail();
        setAutoSteeringWheelHeatSwitchValue(true);
        lockWait();
        Assert.assertTrue(halValue);
        Assert.assertEquals(halStatus, 0);

        setCEM(VehicleConstants.CAR_MODE_DYNO, VehicleConstants.USG_MODE_ACTIVE);//触发false
        lockWait();
        setCEM(VehicleConstants.CAR_MODE_NOMAL, VehicleConstants.USG_MODE_DRIVING);//恢复用户设置的值
        lockWait();
        Assert.assertTrue(halValue);
        Assert.assertEquals(halStatus, 0);
    }
    @Test
    public void testAutoSteerWheelHeatDynoToOtherLastTrue() {//Dyno->other 触发的恢复上次设置的值，上次值为true
        setAutoSteeringWheelHeatSwitchAvail();
        setAutoSteeringWheelHeatSwitchValue(true);
        lockWait();
        Assert.assertTrue(halValue);
        Assert.assertEquals(halStatus, 0);

        setCEM(VehicleConstants.CAR_MODE_DYNO, VehicleConstants.USG_MODE_DRIVING);//触发false
        lockWait();
        setCEM(VehicleConstants.CAR_MODE_NOMAL, VehicleConstants.USG_MODE_DRIVING);//恢复用户设置的值
        lockWait();
        Assert.assertTrue(halValue);
        Assert.assertEquals(halStatus, 0);
    }

    @Test
    public void testAutoSteerWheelHeatOtherToDriverLastFalse() {//other->driver 触发的恢复上次设置的值，上次值为false
        setAutoSteeringWheelHeatSwitchAvail();
        setAutoSteeringWheelHeatSwitchValue(false);
        lockWait();
        Assert.assertFalse(halValue);
        Assert.assertEquals(halStatus, 0);

        setCEM(VehicleConstants.CAR_MODE_DYNO, VehicleConstants.USG_MODE_ACTIVE);//触发false
        lockWait();
        setCEM(VehicleConstants.CAR_MODE_NOMAL, VehicleConstants.USG_MODE_DRIVING);//恢复用户设置的值
        lockWait();
        Assert.assertFalse(halValue);
        Assert.assertEquals(halStatus, 0);
    }

    @Test
    public void testAutoSteerWheelHeatDynoToOtherLastFalse() {//Dyno->other 触发的恢复上次设置的值，上次值为false
        setAutoSteeringWheelHeatSwitchAvail();
        setAutoSteeringWheelHeatSwitchValue(false);
        lockWait();
        Assert.assertFalse(halValue);
        Assert.assertEquals(halStatus, 0);

        setCEM(VehicleConstants.CAR_MODE_DYNO, VehicleConstants.USG_MODE_DRIVING);//触发false
        lockWait();
        setCEM(VehicleConstants.CAR_MODE_NOMAL, VehicleConstants.USG_MODE_DRIVING);//恢复用户设置的值
        lockWait();
        Assert.assertFalse(halValue);
        Assert.assertEquals(halStatus, 0);
    }


    @Test
    public void testAutoSteerWheelHeatDrvModeChangeToECO() {//驾驶模式切换到ECO导致的关，且可用性变为notActive
        setAutoSteeringWheelHeatSwitchAvail();
        setAutoSteeringWheelHeatSwitchValue(true);
        lockWait();
        Assert.assertTrue(halValue);
        Assert.assertEquals(halStatus, 0);

        int MODE_NORMAL = driveModePropertyId.getPropertyValue(DRIVE_MODE_SELECTION_NORMAL);
        int MODE_ECO = driveModePropertyId.getPropertyValue(DRIVE_MODE_SELECTION_ECO);
        //设置驾驶模式切换
        setDmFuncDriveModeSelect(MODE_NORMAL);
        setDmFuncDriveModeSelect(MODE_ECO);

        lockWait();
        Assert.assertFalse(halValue);
        Assert.assertEquals(halStatus, 1);
    }

    public void lockWait() {
        try {
            synchronized (lock) {
                lock.wait(1000);
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }


    private static void setDmFuncDriveModeSelect(int wrapperDriveMode) {
        mCarPropertyMgr.setIntProperty(driveModePropertyId.getPropertyId(), VehicleAreaType.VEHICLE_AREA_TYPE_GLOBAL, wrapperDriveMode);
        delay();
    }


    public void testAutoSteeringWheelHeatSwitchIsAvail() {
        boolean isAvail = mCarPropertyMgr.isPropertyAvailable(propertyId.getPropertyId(), VehicleAreaType.VEHICLE_AREA_TYPE_GLOBAL);
        Assert.assertTrue(isAvail);
    }

    public void testAutoSteeringWheelHeatSwitchNotAvail() {
        boolean isAvail = mCarPropertyMgr.isPropertyAvailable(propertyId.getPropertyId(), VehicleAreaType.VEHICLE_AREA_TYPE_GLOBAL);
        Assert.assertFalse(isAvail);
    }

    public void setAutoSteeringWheelHeatSwitchValue(boolean value) {
        mCarPropertyMgr.setBooleanProperty(propertyId.getPropertyId(), VehicleAreaType.VEHICLE_AREA_TYPE_GLOBAL, value);
    }

    public void testAutoSteeringWheelHeatSwitchValue(boolean value) {
        boolean halValue = mCarPropertyMgr.getBooleanProperty(propertyId.getPropertyId(), VehicleAreaType.VEHICLE_AREA_TYPE_GLOBAL);
        Assert.assertEquals(halValue, value);
    }

    private static final CarPropertyManager.CarPropertyEventCallback carPropertyEventCallback = new CarPropertyManager.CarPropertyEventCallback() {
        @Override
        public void onChangeEvent(CarPropertyValue carPropertyValue) {
            try {
                Log.d(TAG, carPropertyValue.toString());
                halValue = (boolean) carPropertyValue.getValue();
                halStatus = carPropertyValue.getStatus();
                synchronized (lock) {
                    lock.notify();
                }
            } catch (Exception e) {
                Log.e(TAG, e.getMessage());
            }
        }

        @Override
        public void onErrorEvent(int i, int i1) {
        }
    };


    private static void setConfig() {
        int cemSvcId = 37;
        int[] cemOperIds = {999};
        int ccSvcId = 135;
        int[] ccOperIds = {200};

        boolean retCem = ipcpClient.setConfig(cemSvcId, cemOperIds);
        Assert.assertTrue(retCem);
        boolean retCc = ipcpClient.setConfig(ccSvcId, ccOperIds);
        Assert.assertTrue(retCc);

    }

    public void setAutoSteeringWheelHeatSwitchNotAvail() {
        setCEM(VehicleConstants.CAR_MODE_NOMAL, VehicleConstants.USG_MODE_ABANDON);
        setCarConfig(4);
        delay();
    }

    public void setAutoSteeringWheelHeatSwitchAvail() {
        setCEM(VehicleConstants.CAR_MODE_NOMAL, VehicleConstants.USG_MODE_DRIVING);
        setCarConfig(2);
        delay();
        int MODE_NORMAL = driveModePropertyId.getPropertyValue(DRIVE_MODE_SELECTION_NORMAL);
        setDmFuncDriveModeSelect(MODE_NORMAL);
        delay();
    }

    public void setCEM(int carMode, int usgMode) {
        int cemSvcId = 37;
        int cemOperId = 999;
        String[] cems = {"vehModMngtGlbSafe1CarModSts1", "vehModMngtGlbSafe1UsgModSts"};
        int[] cemValues = {carMode, usgMode};
        boolean cemResult = ipcpClient.setCEMSignal(cemSvcId, cemOperId, cems, cemValues);
        Assert.assertTrue(cemResult);
        delay();
    }

    public void setCarConfig(int carConfigValue) {
        int ccSvcId = 135;
        int ccOperId = 200;
        int[] configs = {186, 13};
        int[] values = {carConfigValue, 4};
        boolean ccResult = getIpcpClient().setCarconfigSignal(ccSvcId, ccOperId, configs, values);
        Assert.assertTrue(ccResult);
        delay();
    }

}
